﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using XrmLibrary.Enums;
using XrmLibrary.MessageStrings;

namespace XrmLibrary.Extensions
{
    public static class EntityExtensions
    {
        private static readonly DateTime CrmMinDate = new DateTime(1, 1, 1);

        /// <summary>
        /// Gets the details of the entity in a delimited String format.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="delimiter">The delimiter.</param>
        /// <returns>Delimited string details of the entity.</returns>
        public static String GetDetails(this Entity entity, String delimiter = ", ")
        {
            ValidateEntityArgument(entity);
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Id: {0}{1}", entity.Id, delimiter);
            foreach(var attribute in entity.Attributes)
            {
                try
                {
                    sb.AppendFormat("{0}: {1}{2}", attribute.Key, attribute.Value, delimiter);
                }
                catch (Exception ex)
                {
                    sb.AppendFormat("{0}: {1}{2}", attribute.Key ?? "DNE", ex.Message, delimiter);
                }
            }
            sb.Remove(sb.Length - delimiter.Length, delimiter.Length);
            return sb.ToString();
        }

        private static void ValidateEntityArgument(Entity entity)
        {
            if(entity == null)
            {
                throw new ArgumentException(ErrorStrings.EntityArgumentIsNull);
            }
        }

        /// <summary>
        /// Iterates over an entities attributes and nulls any values that will cause errors during CRUD operations.
        /// </summary>
        /// <param name="entity">The entity.</param>
        public static void NullInvalidAttributes(this Entity entity)
        {
            string[] keys = entity.Attributes.Keys.ToArray();
            object[] values = entity.Attributes.Values.ToArray();
            for (int i = 0; i < keys.Length; i++ )
            {
                if (values[i] is DateTime)
                {
                    DateTime date = (DateTime)values[i];
                    if (date <= CrmMinDate)
                    {
                        entity[keys[i]] = null;
                        Tracer.Trace("NullInvalidAttributes", "Nulling out invalid datetime attribute '{0}' with value '{1}'", null, null, keys[i], date);
                    }
                }
            }
        }

    }
}
